package com.ivncorp.evnproject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.clustering.view.DefaultClusterRenderer;
import com.google.maps.android.ui.IconGenerator;
import com.ivncorp.evnproject.adapter.MapsCotSearchAdapter;
import com.ivncorp.evnproject.helpers.Utils;
import com.ivncorp.evnproject.helpers.Variables;
import com.ivncorp.evnproject.map.MultiDrawable;
import com.ivncorp.evnproject.map.ObjectMapOffline;
import com.ivncorp.evnproject.model.ObjectCot;

@SuppressLint({ "InflateParams", "DefaultLocale" })
public class ActivityMapOfflineCot extends FragmentActivity implements
		ClusterManager.OnClusterClickListener<ObjectMapOffline>,
		ClusterManager.OnClusterInfoWindowClickListener<ObjectMapOffline>,
		ClusterManager.OnClusterItemClickListener<ObjectMapOffline>,
		ClusterManager.OnClusterItemInfoWindowClickListener<ObjectMapOffline> {

	private ClusterManager<ObjectMapOffline> mClusterManager;
	private GoogleMap mMap;
	private EditText txtSearch;
	private ListView listView;
	private MapsCotSearchAdapter adapter;
	private List<ObjectCot> listSeached = new ArrayList<ObjectCot>();
	private Button btnClear;

	protected int getLayoutId() {
		return R.layout.layout_map_cot;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(getLayoutId());
		getActionBar().setDisplayHomeAsUpEnabled(true);
				
		// Get the button view
		View locationButton = ((View) findViewById(1).getParent())
				.findViewById(2);

		// and next place it, for exemple, on bottom right (as Google Maps app)
		RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton
				.getLayoutParams();
		// position on right bottom
		rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
		rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
		rlp.setMargins(0, 0, 30, 30);

		txtSearch = (EditText) findViewById(R.id.txtMapCotSearch);
		listView = (ListView) findViewById(R.id.listMapsCot);
		btnClear = (Button) findViewById(R.id.btnMapsCotClear);

		adapter = new MapsCotSearchAdapter(getApplicationContext(), listSeached);
		listView.setAdapter(adapter);

		Intent intent = getIntent();

		if (intent.getStringExtra("input").equals("object")) {
			// UploadTable
			// uploadtable=(UploadTable)intent.getSerializableExtra("uploadtable");
		} else if (intent.getStringExtra("input").equals("type")) {
			// show type
			if (Variables.currentListObjectCot.size() != 0)
				setUpMapIfNeeded();
		}

		// change text
		txtSearch.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				String key = txtSearch.getText().toString();
				if (!key.isEmpty()) {
					search(key);
					adapter.notifyDataSetChanged();
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				if (!listView.isShown()) {
					listView.setVisibility(View.VISIBLE);
				}
				if (txtSearch.getText().toString().isEmpty()) {
					listView.setVisibility(View.GONE);
				}
			}
		});

		btnClear.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				txtSearch.setText("");
			}
		});

		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				try {
					ExifInterface exif = new ExifInterface(listSeached.get(
							position).getImage_1());
					float[] LatLong = new float[2];
					exif.getLatLong(LatLong);
					float latitude = LatLong[0];
					float longitude = LatLong[1];
					mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
							new LatLng(latitude, longitude), 15f));
				} catch (IOException e) {
					Toast.makeText(getApplication(), "Eror set GPS",
							Toast.LENGTH_SHORT).show();

				}

				listView.setVisibility(View.GONE);

			}

		});

	}

	@Override
	protected void onResume() {
		super.onResume();
		if (Variables.currentListObjectCot.size() != 0)
			setUpMapIfNeeded();
	}

	private void setUpMapIfNeeded() {
		if (mMap != null) {
			return;
		}
		mMap = ((SupportMapFragment) getSupportFragmentManager()
				.findFragmentById(R.id.mapCot)).getMap();
		if (mMap != null) {
			mMap.setMyLocationEnabled(true);
			mMap.getUiSettings().setZoomControlsEnabled(false);
			startDemo();
		}
	}

	protected GoogleMap getMap() {
		if (Variables.currentListObjectCot.size() != 0)
			setUpMapIfNeeded();
		return mMap;
	}

	private class ObjectMapOfflineRenderer extends
			DefaultClusterRenderer<ObjectMapOffline> {
		private final IconGenerator mIconGenerator = new IconGenerator(
				getApplicationContext());
		private final IconGenerator mClusterIconGenerator = new IconGenerator(
				getApplicationContext());
		private final ImageView mImageView;
		private final ImageView mClusterImageView;
		private final int mDimension;

		public ObjectMapOfflineRenderer() {
			super(getApplicationContext(), getMap(), mClusterManager);

			View multiProfile = getLayoutInflater().inflate(
					R.layout.multi_profile, null);
			mClusterIconGenerator.setContentView(multiProfile);
			mClusterImageView = (ImageView) multiProfile
					.findViewById(R.id.image);

			mImageView = new ImageView(getApplicationContext());
			mDimension = (int) getResources().getDimension(
					R.dimen.custom_profile_image);
			mImageView.setLayoutParams(new ViewGroup.LayoutParams(mDimension,
					mDimension));
			int padding = (int) getResources().getDimension(
					R.dimen.custom_profile_padding);
			mImageView.setPadding(padding, padding, padding, padding);
			mIconGenerator.setContentView(mImageView);
		}

		@Override
		protected void onBeforeClusterItemRendered(
				ObjectMapOffline ObjectMapOffline, MarkerOptions markerOptions) {
			// Draw a single ObjectMapOffline.
			// Set the info window to show their name.
			// mImageView.setImageResource(R.drawable.gran);
			mImageView.setImageBitmap(Utils.decodeFile(
					ObjectMapOffline.profilePhoto, mDimension, mDimension));
			Bitmap icon = mIconGenerator.makeIcon();
			markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).title(
					ObjectMapOffline.name);
		}

		@Override
		protected void onBeforeClusterRendered(
				Cluster<ObjectMapOffline> cluster, MarkerOptions markerOptions) {
			// Draw multiple people.
			// Note: this method runs on the UI thread. Don't spend too much
			// time in here (like in this example).
			List<Drawable> profilePhotos = new ArrayList<Drawable>(Math.min(4,
					cluster.getSize()));
			int width = mDimension;
			int height = mDimension;

			for (ObjectMapOffline p : cluster.getItems()) {
				// Draw 4 at most.
				if (profilePhotos.size() == 4)
					break;

				Drawable drawable = new BitmapDrawable(
						getResources(),
						Utils.decodeFile(p.profilePhoto, mDimension, mDimension));
				drawable.setBounds(0, 0, width, height);
				profilePhotos.add(drawable);
			}
			MultiDrawable multiDrawable = new MultiDrawable(profilePhotos);
			multiDrawable.setBounds(0, 0, width, height);

			mClusterImageView.setImageDrawable(multiDrawable);
			Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster
					.getSize()));
			markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
		}

		@Override
		protected boolean shouldRenderAsCluster(
				@SuppressWarnings("rawtypes") Cluster cluster) {
			// Always render clusters.
			return cluster.getSize() > 1;
		}
	}

	@Override
	public boolean onClusterClick(Cluster<ObjectMapOffline> cluster) {
		// Show a toast with some info when the cluster is clicked.
		String firstName = cluster.getItems().iterator().next().name;
		Toast.makeText(this,
				cluster.getSize() + " (including " + firstName + ")",
				Toast.LENGTH_SHORT).show();
		return true;
	}

	@Override
	public void onClusterInfoWindowClick(Cluster<ObjectMapOffline> cluster) {
		// Does nothing, but you could go to a list of the users.
	}

	@Override
	public boolean onClusterItemClick(ObjectMapOffline item) {
		// Does nothing, but you could go into the user's profile page, for
		// example.
		return false;
	}

	@Override
	public void onClusterItemInfoWindowClick(ObjectMapOffline item) {
		// Does nothing, but you could go into the user's profile page, for
		// example.
	}

	protected void startDemo() {
		try {
			ExifInterface exif = new ExifInterface(
					Variables.currentListObjectCot.get(0).getImage_1());
			float[] LatLong = new float[2];
			exif.getLatLong(LatLong);
			float latitude = LatLong[0];
			float longitude = LatLong[1];
			getMap().moveCamera(
					CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,
							longitude), 11.5f));
		} catch (IOException e) {
			Toast.makeText(getApplication(), "Eror set GPS", Toast.LENGTH_SHORT)
					.show();

		}
		mClusterManager = new ClusterManager<ObjectMapOffline>(this, getMap());
		mClusterManager.setRenderer(new ObjectMapOfflineRenderer());
		getMap().setOnCameraChangeListener(mClusterManager);
		getMap().setOnMarkerClickListener(mClusterManager);
		getMap().setOnInfoWindowClickListener(mClusterManager);
		mClusterManager.setOnClusterClickListener(this);
		mClusterManager.setOnClusterInfoWindowClickListener(this);
		mClusterManager.setOnClusterItemClickListener(this);
		mClusterManager.setOnClusterItemInfoWindowClickListener(this);
		addItems();
		mClusterManager.cluster();
	}

	private void addItems() {

		ExifInterface exif;
		for (ObjectCot element : Variables.currentListObjectCot) {
			if (element.getImage_1() != null) {
				try {
					exif = new ExifInterface(element.getImage_1());
					float[] LatLong = new float[2];
					exif.getLatLong(LatLong);
					float latitude = LatLong[0];
					float longitude = LatLong[1];
					mClusterManager.addItem(new ObjectMapOffline(new LatLng(
							latitude, longitude), element.getName(), element
							.getImage_1()));
				} catch (IOException e) {
					Toast.makeText(getApplication(), "Eror set GPS",
							Toast.LENGTH_SHORT).show();

				}
			}
		}
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case android.R.id.home:
			finish();
			break;

		default:
			break;
		}
		return super.onMenuItemSelected(featureId, item);
	}

	@SuppressLint("DefaultLocale")
	private void search(String key) {
		listSeached.clear();
		int count = 0;
		for (ObjectCot cot : Variables.currentListObjectCot) {
			if (cot.getName().toLowerCase().contains(key.toLowerCase())) {
				listSeached.add(cot);
				count++;
			}
			if (count == 5)
				break;
		}
	}

}
